package com.cxb.utils;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import android.app.Activity;
import android.content.Context;
import android.content.res.AssetFileDescriptor;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;
import android.util.Log;

/**
 * 
 * @{# CitysDBHelp.java Create on 2012-11-26 ����11:36:29
 * 
 *     �๦��˵��:��װ��������ݿ����
 * @Version 1.0
 * @Author ��ΰ��
 * 
 * 
 */
public class CitysDBHelp {

	private Context mContext = null;

	private SQLiteOpenHelper dbHelper = null;

	// ��ݿ���
	private String fileName = "city_location.db";

	public CitysDBHelp(Context context) {
		this.mContext = context;
		dbHelper = DataBaseHelper.getInstance(context);
		moveDBFile(context, "city_location.db");

	}
	/**
	 * 说明:移动数据库文件(从asset目录下移动context目录下)
	 * Author:陈伟斌
	 * 2012-12-6
	 */
	public static void moveDBFile(Context context, String dbName) {
		////////////////////////////////////////////
		
		if(context.getDatabasePath(dbName).exists()){
			 try {
				AssetFileDescriptor fd=context.getAssets().openFd(dbName);
				File dbFile=context.getDatabasePath(dbName);
				
				if(dbFile.length()!=fd.getLength()){
					dbFile.delete();
				}
			} catch (IOException e) {
				
				e.printStackTrace();
			}
		}
		///////////////////////////////////////////////
		if (!context.getDatabasePath(dbName).exists()) {

			try {
				InputStream inStream = context.getAssets().open(dbName);
				File file = new File(context.getDatabasePath(dbName).toString()
						.substring(0, context.getDatabasePath(dbName).toString().indexOf(dbName)));
				if (!file.exists())
					file.mkdir();
				OutputStream outStream = new FileOutputStream(context.getDatabasePath(dbName).toString());
				byte[] buffer = new byte[1024];
				int length = 0;
				while ((length = inStream.read(buffer)) > 0) {
					outStream.write(buffer, 0, length);
				}
				outStream.flush();
				outStream.close();
				inStream.close();
			} catch (Exception e) {
				e.printStackTrace();
			}
		}
	}
	public String getProvinceNameFromCityName(String cityName) {
		String provinceName = null;
		try {
			SQLiteDatabase db = mContext.openOrCreateDatabase(fileName,
					Activity.MODE_PRIVATE, null);

			String sql = "select pro from city_location where procity = '"
					+ cityName + "'";
			Cursor cursor = db.rawQuery(sql, null);
			while (cursor.moveToNext()) {
				provinceName = cursor.getString(cursor.getColumnIndex("pro"));
			}
			cursor.deactivate();
			cursor.close();
			db.close();
		} catch (Exception e) {
			e.printStackTrace();
		}
		return provinceName;
	}
	/**
	 * 
	 * ������������ݾ�γ�Ȳ�ѯ����ݿ���еľ�γ����̾���
	 * 
	 * @param latitude
	 * @param longtitude
	 */
	public String getMinimumDistance(double latitude, double longtitude) {
		String cityCode = "";
		try {

			double min = 100000000000.0D;
			SQLiteDatabase db = mContext.openOrCreateDatabase(fileName,
					Activity.MODE_PRIVATE, null);

			String sql = "SELECT * from city_location";
			Cursor cursor = db.rawQuery(sql, null);
			while (cursor.moveToNext()) {

				double lg = cursor
						.getDouble(cursor.getColumnIndex("Longitude"));
				double la = cursor.getDouble(cursor.getColumnIndex("Latitude"));

				double value = getDistance(la / 1000000, lg / 1000000,
						latitude, longtitude);

				if (value < min) {
					min = value;
					cityCode = cursor.getString(cursor.getColumnIndex("procity"));
				}
			}
			cursor.deactivate();
			cursor.close();
			db.close();
			Debug.printf("test", "--- min " + min + "  cityName = " + cityCode
					+ " la = " + latitude + "  lg = " + longtitude);
		} catch (Exception e) {
			e.printStackTrace();
		}

		return cityCode;
	}
	
	public String getMinDistanceCityName(double latitude, double longtitude) {
		String cityName = "";
		try {

			double min = 100000000000.0D;
			SQLiteDatabase db = mContext.openOrCreateDatabase(fileName,
					Activity.MODE_PRIVATE, null);

			String sql = "SELECT * from city_location";
			Cursor cursor = db.rawQuery(sql, null);
			while (cursor.moveToNext()) {

				double lg = cursor
						.getDouble(cursor.getColumnIndex("Longitude"));
				double la = cursor.getDouble(cursor.getColumnIndex("Latitude"));

				double value = getDistance(la, lg ,
						latitude, longtitude);

				if (value < min) {
					min = value;
					cityName = cursor.getString(cursor.getColumnIndex("procity"));
				}
			}
			cursor.deactivate();
			cursor.close();
			db.close();
			Debug.printf("test", "--- min " + min + "  cityName = " + cityName
					+ " la = " + latitude + "  lg = " + longtitude);
		} catch (Exception e) {
			e.printStackTrace();
		}

		return cityName;
	}
	/**
	 * 
	 * ������������ݾ�γ�Ȳ�ѯ����ݿ���еľ�γ����̾���
	 * 
	 * @param latitude
	 * @param longtitude
	 */
	public String getMinDistanceCityCode(double latitude, double longtitude) {
		String cityCode = "";
		try {

			double min = 100000000000.0D;
			SQLiteDatabase db = mContext.openOrCreateDatabase(fileName,
					Activity.MODE_PRIVATE, null);

			String sql = "SELECT * from city_location";
			Cursor cursor = db.rawQuery(sql, null);
			while (cursor.moveToNext()) {

				double lg = cursor
						.getDouble(cursor.getColumnIndex("Longitude"));
				double la = cursor.getDouble(cursor.getColumnIndex("Latitude"));

				double value = getDistance(la, lg ,
						latitude, longtitude);

				if (value < min) {
					min = value;
					cityCode = cursor.getString(cursor.getColumnIndex("code"));
				}
			}
			cursor.deactivate();
			cursor.close();
			db.close();
			Debug.printf("test", "--- min " + min + "  cityName = " + cityCode
					+ " la = " + latitude + "  lg = " + longtitude);
		} catch (Exception e) {
			e.printStackTrace();
		}

		return cityCode;
	}
//
//	/**
//	 * 
//	 * ������������ݾ�γ�Ȳ�ѯ����ݿ���еľ�γ����̾���ĵ����б�
//	 * 
//	 * @param latitude
//	 * @param longtitude
//	 */
//	public List<String> getMinimumDistanceList(double latitude,
//			double longtitude) {
//
//		List<String> list = new ArrayList<String>();
//		HashMap<String, Double> map = new HashMap<String, Double>();
//		try {
//
//			double min = 100000000000.0D;
//			SQLiteDatabase db = mContext.openOrCreateDatabase(fileName,
//					Activity.MODE_PRIVATE, null);
//			// String sql = "SELECT city_name from cities order by (cos(" +
//			// longtitude + ") * cos(longitude) * cos( " + latitude +
//			// "- latitude ) + sin(" + longtitude +
//			// ") * sin(longitude)) desc limit ?";
//			String sql = "SELECT * from city_location";
//			Cursor cursor = db.rawQuery(sql, null);
//			while (cursor.moveToNext()) {
//
//				double lg = cursor
//						.getDouble(cursor.getColumnIndex("longitude"));
//				double la = cursor.getDouble(cursor.getColumnIndex("latitude"));
//				String cityCode = cursor.getString(cursor
//						.getColumnIndex("code"));
//				String city = cursor
//						.getString(cursor.getColumnIndex("procity"));
//				String province = cursor
//						.getString(cursor.getColumnIndex("pro"));
//
//				// ��������λ�õľ��빫ʽ
//				// ACOS(cos(@longitude) * cos(longitude) * cos(@latitude-
//				// latitude ) + sin(@longitude) * sin(longitude)) asc
//				// double value = Math.acos(Math.cos((long) (longtitude *
//				// 1000000)) * Math.cos(lg) * Math.cos(((long) (latitude *
//				// 1000000)) - la) + Math.sin((long)(longtitude * 1000000)) *
//				// Math.sin(lg));*/
//				double value = getDistance(la / 1000000, lg / 1000000,
//						latitude, longtitude);
//				// map.put(province + "-" + city, value);
//				Debug.printf("test", province + " - " + city);
//				map.put(cityCode, value);
//			}
//			cursor.deactivate();
//			cursor.close();
//			db.close();
//
//			list = sortMap(map);
//
//		} catch (Exception e) {
//			e.printStackTrace();
//		}
//
//		return list;
//	}

	/**
	 * 
	 * ����������ΪMap��ĳ����б����򣬻�ȡ��̵�������10������
	 * 
	 * @param map
	 * @return
	 */
	private List<String> sortMap(Map<String, Double> map) {
		ArrayList<String> list = new ArrayList<String>();
		try {
			// ����Map���
			List<Map.Entry<String, Double>> mappingList = null;
			// ͨ��ArrayList���캯���map.entrySet()ת����list
			mappingList = new ArrayList<Map.Entry<String, Double>>(
					map.entrySet());
			// ͨ��Ƚ���ʵ�ֱȽ�����
			Collections.sort(mappingList,
					new Comparator<Map.Entry<String, Double>>() {
						public int compare(Map.Entry<String, Double> mapping1,
								Map.Entry<String, Double> mapping2) {
							return mapping1.getValue().compareTo(
									mapping2.getValue());
						}
					});
			int i = 0;
			String cityCode;
			for (Map.Entry<String, Double> mapping : mappingList) {
				// System.out.println(mapping.getKey() + ":" +
				// mapping.getValue());
				if (i < 10) {
					cityCode = mapping.getKey();
					Debug.printf("vita", "--- min " + mapping.getValue() + "  city = "
							+ cityCode);
					list.add(cityCode);
				}
				i++;
			}
		} catch (Exception e) {
			e.printStackTrace();
		}

		return list;
	}

	private final static double EARTH_RADIUS = 6378.137;

	private static double rad(double d) {
		return d * Math.PI / 180.0;
	}

	public static double getDistance(double lat1, double lng1, double lat2,
			double lng2) {
		double radLat1 = rad(lat1);
		double radLat2 = rad(lat2);
		double a = radLat1 - radLat2;
		double b = rad(lng1) - rad(lng2);
		double s = 2 * Math.asin(Math.sqrt(Math.pow(Math.sin(a / 2), 2)
				+ Math.cos(radLat1) * Math.cos(radLat2)
				* Math.pow(Math.sin(b / 2), 2)));
		s = s * EARTH_RADIUS;
		s = Math.round(s * 10000) / 10000;
		return s;
	}
	/**
	 * ��ȡ���д���
	 * @return
	 * ��ΰ��
	 * 2013-10-28
	 */
	public String getcityCode(String city){
		if(city.endsWith("��")||city.endsWith("��")){
			city=city.substring(0, city.length()-1);
		}
		SQLiteDatabase db = mContext.openOrCreateDatabase(fileName,
				Activity.MODE_PRIVATE, null);

		String sql = "SELECT * from city_location where procity='"+city+"'";
		Cursor cursor = db.rawQuery(sql, null);
		String cityCode=null;
		if(cursor.moveToNext()){
			cityCode=cursor.getString(cursor.getColumnIndex("code"));
		}
		return cityCode;
	}

	

}
